<template>
  <div :id="container" class="map"></div>
  <div class="mode-switch">
    <el-radio-group v-model="mapMode" @change="changeMapMode">
      <el-radio-button label="2D">2D</el-radio-button>
      <el-radio-button label="3D">3D</el-radio-button>
    </el-radio-group>
  </div>
  <div class="base-switch">
    <el-radio-group v-model="baseLayer" @change="changeBaseLayer">
      <el-radio-button label="vec">矢量</el-radio-button>
      <el-radio-button label="img">影像</el-radio-button>
    </el-radio-group>
  </div>
  <div class="layer-switch">
    <el-tree
        :data="treeData"
        :props="treeProps"
        :default-expand-all="false"
        @node-click="handleNodeClick" />
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'

// import * as Cesium from 'cesium';

import { TILEURL, treeDatas } from '../../assets/data/common.js'
import { onEntityClickEvent } from '../../utils/event'
import {
  addPoints,
  addLabels,
  addBillboard,
  addHeightPoints,
  addLines,
  addPolygons,
  addBox,
  addCorridors,
  addEllipses,
  addEllipsoid,
  addPlanes,
  addWalls,
  addModels,
  addRectangle,
  addImage
} from '../../utils/entity'

import faceImg from "../../assets/imgs/face.png";

const props = defineProps({
  container: {
    type: String,
    default: () => 'map'
  },
  center: {
    type: Array<number>,
    default: () => [113.752, 35.957]
  }
})

let viewer = null
let mapMode = ref('3D')
let baseLayer = ref('img')

let treeProps = {
  children: 'children',
  label: 'label',
}
const treeData = treeDatas

onMounted(() => {
  initMap()
})

function getLayer(url, subdomains = []) {
  return new Cesium.UrlTemplateImageryProvider({
    url: url,
    subdomains: subdomains
  })
}

let layerImg, layerImgLabel, layerVec, layerVecLabel

function initMap() {
  layerImg = getLayer(TILEURL.TDT_IMG.url, TILEURL.TDT_IMG.subdomains)
  const terrainProvider = new Cesium.CesiumTerrainProvider({
    url: 'http://localhost:8086/dem1',
    //请求水波纹效果
    requestWaterMask: true,
    //请求照明
    requestVertexNormals: true
  });
  viewer = new Cesium.Viewer(props.container, {
    infoBox: false,
    animation: false, //是否创建动画小器件，左下角仪表
    timeline: false, //是否显示时间线控件
    geocoder: false, //是否显示地名查找控件
    baseLayerPicker: false, //是否显示图层选择控件
    homeButton: false,
    sceneModePicker: false,
    navigationHelpButton: false,
    fullscreenButton: false,
    vrButton: false,
    selectionIndicator: false,
    imageryProvider: layerImg,
    terrainProvider,
    shouldAnimate: true
  });
  window.viewer = viewer

  layerImg = viewer.scene.imageryLayers.get(0)
  layerImgLabel = viewer.scene.imageryLayers.addImageryProvider(getLayer(TILEURL.TDT_IMG_LBL.url, TILEURL.TDT_IMG_LBL.subdomains))
  layerVec = viewer.scene.imageryLayers.addImageryProvider(getLayer(TILEURL.TDT_VEC.url, TILEURL.TDT_VEC.subdomains))
  layerVecLabel = viewer.scene.imageryLayers.addImageryProvider(getLayer(TILEURL.TDT_VEC_LBL.url, TILEURL.TDT_VEC_LBL.subdomains))
  layerVec.show = false
  layerVecLabel.show = false

  //去cesium logo水印
  viewer.cesiumWidget.creditContainer.style.display = "none";
  // 初始化场景位置
  // viewer.camera.position
  // viewer.camera.heading
  // viewer.camera.pitch
  // viewer.camera.roll
  viewer.scene.camera.setView({
    // 初始化相机经纬度
    destination : new Cesium.Cartesian3.fromDegrees(props.center[0], props.center[1],  8000000),
    orientation: {
      // 指向
      heading: 6.3,
      // 视角
      pitch: -1.57,
      roll: 0
    }
  });
  onEntityClickEvent(viewer)
}

function changeMapMode() {
  if(mapMode.value === '3D') {
    viewer.scene.mode = Cesium.SceneMode.SCENE3D
  } else {
    viewer.scene.mode = Cesium.SceneMode.SCENE2D
  }
}

function changeBaseLayer() {
  if(baseLayer.value === 'img') {
    layerImg.show = true
    layerImgLabel.show = true
    layerVec.show = false
    layerVecLabel.show = false
  } else {
    layerVec.show = true
    layerVecLabel.show = true
    layerImg.show = false
    layerImgLabel.show = false
  }
}

function clearEntities() {
  viewer.entities.removeAll()
}

function handleNodeClick(data) {
  clearEntities()
  let zoom = true
  if(data.type === 'service') {
    switch (data.label) {
      case 'wms': {
        const provider = new Cesium.WebMapServiceImageryProvider({
          url : data.value.url,
          layers : data.value.layers,
          parameters: {
            service: 'WMS',
            format: 'image/png',
            transparent: true
          }
        });
        viewer.imageryLayers.addImageryProvider(provider);
        break
      }
      case 'mapbox': {
        const provider = new Cesium.MapboxStyleImageryProvider(data.value)
        viewer.imageryLayers.addImageryProvider(provider);
        break
      }
      case 'xyz-tile': {
        const provider = new Cesium.UrlTemplateImageryProvider({
          url: data.value.url,
          subdomains: data.value.subdomains
        })
        const layer = viewer.scene.imageryLayers.addImageryProvider(provider);
        //50%透明度
        // layer.alpha = 1;
        //两倍亮度
        // layer.brightness = 1.0;
        break
      }
      case 'tms-tile': {
        const provider = new Cesium.UrlTemplateImageryProvider({
          url: data.value.url,
          subdomains: data.value.subdomains
        })
        const layer = viewer.scene.imageryLayers.addImageryProvider(provider);
        //50%透明度
        // layer.alpha = 1;
        //两倍亮度
        // layer.brightness = 1.0;
        break
      }
      case 'wmts': {
        const url = data.value.url.split('{layer}').join(data.value.layer)
        const provider = new Cesium.WebMapTileServiceImageryProvider({
          url : url,
          style : '',
          layer: data.value.layer,
          tileMatrixSetID:'EPSG:900913'
        });
        const layer = viewer.scene.imageryLayers.addImageryProvider(provider);
        //50%透明度
        // layer.alpha = 1;
        //两倍亮度
        // layer.brightness = 1.0;
        break
      }
      case '3dtiles-osgb': {
        const tileset = new Cesium.Cesium3DTileset({
          url: data.value.url
        });
        viewer.scene.primitives.add(tileset);
        viewer.zoomTo(tileset);
        zoom = false
        break
      }
      case '3dtiles-shp': {
        const tileset = new Cesium.Cesium3DTileset({
          url: data.value.url,
          "color" : {
            "conditions" : [
              ["(${Floor} >= 1.0)  && (${Floor} < 10.0)", "color('#FF00FF')"],
              ["(${Floor} >= 10.0) && (${Floor} < 30.0)", "color('#FF0000')"],
              ["(${Floor} >= 30.0) && (${Floor} < 50.0)", "color('#FFFF00')"],
              ["(${Floor} >= 50.0) && (${Floor} < 70.0)", "color('#00FF00')"],
              ["(${Floor} >= 70.0) && (${Floor} < 100.0)", "color('#00FFFF')"],
              ["(${Floor} >= 100.0)", "color('#0000FF')"]
            ]
          }
        });
        viewer.scene.primitives.add(tileset);
        viewer.zoomTo(tileset);
        zoom = false
        break
      }
    }
  } else if(data.type === 'data') {
    switch (data.label) {
      case 'czml': {
        fetch(`data/${data.value}`).then(res => {
          return res.json()
        }).then(json => {
          const dataSourcePromise = Cesium.CzmlDataSource.load(json);
          viewer.dataSources.add(dataSourcePromise);
          viewer.zoomTo(dataSourcePromise);
        })
        break;
      }
      case 'kml': {
        const options = {
          camera: viewer.scene.camera,
          canvas: viewer.scene.canvas,
          screenOverlayContainer: viewer.container,
        };
        viewer.dataSources.add(
            Cesium.KmlDataSource.load(
                `data/${data.value}`,
                options
            )
        ).then(function (dataSource) {
          viewer.flyTo(viewer.entities, {
            duration: 3
          });
          const rider = dataSource.entities.getById("tour");
          viewer.flyTo(rider).then(function () {
              viewer.trackedEntity = rider;
              viewer.selectedEntity = viewer.trackedEntity;
              viewer.clock.multiplier = 30;
              viewer.clock.shouldAnimate = true;
          })
        })
        break;
      }
      case 'geojson-point': {
        const promise = Cesium.GeoJsonDataSource.load(`data/${data.value}`);
        promise.then(function(dataSource) {
          viewer.dataSources.add(dataSource);
          const entities = dataSource.entities.values;
          for (let i = 0; i < entities.length; i++) {
            let entity = entities[i];
            entity.billboard.image = faceImg
            entity.billboard.scale = 1
            entity.billboard.verticalOrigin = Cesium.VerticalOrigin.CENTER
          }
          viewer.flyTo(promise);
        });
        break;
      }
      case 'geojson-line': {
        const promise = Cesium.GeoJsonDataSource.load(`data/${data.value}`);
        promise.then(function(dataSource) {
          viewer.dataSources.add(dataSource);
          const entities = dataSource.entities.values;
          for (let i = 0; i < entities.length; i++) {
            let entity = entities[i];
            entity.polyline.width = 1.1
            entity.polyline.material = Cesium.Color.RED
          }
          viewer.flyTo(promise);
        });
        break;
      }
      case 'geojson-polygon': {
        const promise = Cesium.GeoJsonDataSource.load(`data/${data.value}`);
        promise.then(function(dataSource) {
          viewer.dataSources.add(dataSource);
          const entities = dataSource.entities.values;
          let colorHash = {};
          for (let i = 0; i < entities.length; i++) {
            let entity = entities[i];
            const name = entity.name;
            let color = colorHash[name];
            if (!color) {
              color = Cesium.Color.fromRandom({
                alpha : 1.0
              });
              colorHash[name] = color;
            }
            entity.polygon.material = color;
            entity.polygon.outline = false;
            entity.polygon.extrudedHeight = 5000.0;
          }
          viewer.flyTo(promise);
        });
        break;
      }
      case 'geojson-building': {
        const promise = Cesium.GeoJsonDataSource.load(`data/${data.value}`);
        promise.then(function(dataSource) {
          viewer.dataSources.add(dataSource);
          const entities = dataSource.entities.values;
          for (let i = 0; i < entities.length; i++) {
            let entity = entities[i];
            let color = Cesium.Color.fromRandom({
              alpha : 0.6
            })
            const h = 3 * entity.properties.Floor.getValue()
            entity.polygon.material = color;
            entity.polygon.outline = false;// polygon边线显示与否
            entity.polygon.height = h;//底面距离地面高度
            entity.polygon.extrudedHeight = 0;//顶面距离地面高度
          }
          viewer.flyTo(promise);
        });
        break;
      }
    }
  } else {
    switch (data.value) {
      case 'points' :{
        addPoints()
        break
      }
      case 'billboard' :{
        addBillboard()
        break
      }
      case 'pointsH' :{
        addHeightPoints()
        break
      }
      case 'polylines' :{
        addLines()
        break
      }
      case 'polygons' :{
        addPolygons()
        break
      }
      case 'box' :{
        addBox()
        break
      }
      case 'corridor' :{
        addCorridors()
        break
      }
      case 'ellipse' :{
        addEllipses()
        break
      }
      case 'ellipsoid' :{
        addEllipsoid()
        break
      }
      case 'label' :{
        addLabels()
        break
      }
      case 'plane': {
        addPlanes()
        break;
      }
      case 'wall': {
        addWalls()
        break
      }
      case 'model': {
        addModels()
        break
      }
      case 'rectangle': {
        addRectangle()
        break
      }
      case 'image': {
        addImage()
        break
      }
    }
  }
  if(zoom) {
    viewer.flyTo(viewer.entities, {
      duration: 3
    });
  }
}
</script>



<style scoped lang="scss">
.map {
  height: 100%;
  overflow: hidden;
}
.mode-switch {
  position: absolute;
  top: 1rem;
  right: 1rem;
  z-index: 99;
}
.base-switch {
  position: absolute;
  top: 1rem;
  right: 9rem;
  z-index: 99;
}
.layer-switch {
  position: absolute;
  top: 4rem;
  right: 1rem;
  z-index: 99;
  width: 15rem;
  max-height: 20rem;
  overflow-y: auto;
  padding: 1rem;
  background-color: white;
  border-radius: 0.3rem;
}
</style>
<style lang="scss">
@import "popup";
</style>
